home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / vsoup11.zip / smtp.cc < prev    next >
C/C++ Source or Header  |  1996-09-01  |  5KB  |  219 lines

  1. //  $Id: smtp.cc 1.10 1996/09/01 12:13:29 hardy Exp $
  2. //
  3. //  This progam/module was written by Hardy Griech based on ideas and
  4. //  pieces of code from Chin Huang (cthuang@io.org).  Bug reports should
  5. //  be submitted to rgriech@ibm.net.
  6. //
  7. //  This file is part of soup++ for OS/2.  Soup++ including this file
  8. //  is freeware.  There is no warranty of any kind implied.  The terms
  9. //  of the GNU Gernal Public Licence are valid for this piece of software.
  10. //
  11. //  Send mail reply packet using SMTP directly
  12. //
  13.  
  14.  
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20. #include "global.hh"
  21. #include "mts.hh"
  22. #include "smtp.hh"
  23. #include "socket.hh"
  24. #include "util.hh"
  25.  
  26.  
  27.  
  28. void smtpClose(TSocket &socket)
  29. //
  30. //  close SMTP connection
  31. //
  32. {
  33. #ifdef DEBUG
  34.     printfT( "smtpClose(): QUIT\n" );
  35. #endif
  36.     socket.puts("QUIT");
  37.     socket.close();
  38. }   // smtpClose
  39.  
  40.  
  41.  
  42. static int getSmtpReply( TSocket &socket, char *response)
  43. //
  44. //  get a response from the SMTP server and test it
  45. //
  46. {
  47.     char buf[BUFSIZ];
  48.  
  49.     do {
  50.     buf[3] = '\0';
  51.     socket.gets(buf, BUFSIZ);
  52.     } while (buf[3] == '-');        /* wait until not a continuation */
  53.  
  54.     if (strncmp(buf, response, 3) != 0) {
  55.     areas.mailPrintf1(1, "Expecting SMTP %s reply, got %s\n", response, buf);
  56.     }
  57.     return (buf[0] == *response);    /* only first digit really matters */
  58. }   // getSmtpReply
  59.  
  60.  
  61.  
  62. int smtpConnect ( TSocket &socket )
  63. //
  64. //  Open socket and intialize connection to SMTP server.
  65. //  return value != 0  -->  ok
  66. //
  67. {
  68.     if (socket.open( smtpInfo.host,"smtp","tcp" ) < 0)
  69.     return 0;
  70.  
  71.     if (!getSmtpReply(socket, "220")) {
  72.     areas.mailPrintf1( 1,"Disconnecting from %s\n", smtpInfo.host);
  73.     smtpClose(socket);
  74.     return 0;
  75.     }
  76.  
  77.     socket.printf("HELO %s\n", hostName);
  78.     if (!getSmtpReply(socket, "250")) {
  79.     areas.mailPrintf1( 1,"Disconnecting from %s\n", smtpInfo.host);
  80.     smtpClose(socket);
  81.     return 0;
  82.     }
  83.     return 1;
  84. }   // smtpConnect
  85.     
  86.  
  87.  
  88. static void sendSmtpRcpt( TSocket &socket, const char *buf )
  89. //
  90. //  Send RCPT command.
  91. //
  92. {
  93.     areas.mailPrintf1(1,"%s: mailing to %s\n", progname, buf);
  94.     socket.printf( "RCPT TO:<%s>\r\n", buf );
  95.     getSmtpReply(socket, "250");
  96. }   // sendSmtpRcpt
  97.  
  98.  
  99.  
  100. static void putAddresses( TSocket &socket, char *addresses )
  101. //
  102. //  Send an RCPT command for each address in the address list.
  103. //
  104. {
  105.     const char *srcEnd;
  106.     char *startAddr;
  107.     char *endAddr;
  108.     char saveCh;
  109.     const char *addr;
  110.     
  111.     srcEnd = strchr(addresses, '\0');
  112.     startAddr = addresses;
  113.  
  114.     while (startAddr < srcEnd) {
  115.     endAddr = findAddressSep(startAddr);
  116.     saveCh = *endAddr;
  117.     *endAddr = '\0';
  118.     addr = extractAddress(startAddr);
  119.     if (addr) {
  120.         sendSmtpRcpt(socket, addr);
  121.         //// delete addr;
  122.     }
  123.     *endAddr = saveCh;
  124.     startAddr = endAddr + 1;
  125.     }
  126. }   // putAddresses
  127.  
  128.  
  129.  
  130. int smtpMail( TSocket &socket, FILE *fd, size_t bytes)
  131. //
  132. //  Send message to SMTP server. 
  133. //
  134. {
  135.     const char *addr;
  136.     char buf[BUFSIZ], *addrs, ch;
  137.     const char *from;
  138.     char *resentTo;
  139.     char *s;
  140.     char more;
  141.     long offset;
  142.     size_t count;
  143.  
  144.     /* Look for From header and send MAIL command to SMTP server. */
  145.     from = getHeader(fd, "From");
  146.     if (from == NULL || (addr = extractAddress(from)) == NULL) {
  147.     areas.mailPrintf1( 1,"%s: no address in From header", progname );
  148.     if (from != NULL)
  149.         delete from;
  150.     return 0;
  151.     }
  152.     areas.mailPrintf1(1,"%s: mailing from %s\n", progname, addr);
  153.     socket.printf("MAIL FROM:<%s>\r\n", addr);
  154.     //// delete from;
  155.     //// delete addr;
  156.     if ( !getSmtpReply(socket, "250")) {
  157.     return 0;
  158.     }
  159.  
  160.     offset = ftell(fd);
  161.     if ((resentTo = (char *)getHeader(fd, "Resent-To")) != NULL) {
  162.     /* Send to address on Resent-To header. */
  163.     putAddresses(socket, resentTo);
  164.     //// delete resentTo;
  165.     }
  166.     else {
  167.     /* Send to addresses on To, Cc and Bcc headers. */
  168.     more = fgets(buf, sizeof(buf), fd) != 0;
  169.     while (more) {
  170.         if (buf[0] == '\n')
  171.         break;
  172.  
  173.         if (isHeader(buf, "To")  ||  isHeader(buf, "Cc")  ||  isHeader(buf, "Bcc")) {
  174.         addrs = buf;
  175.         while (*addrs != '\0' && !isspace(*addrs)) {
  176.             ++addrs;
  177.         }
  178.         putAddresses(socket, addrs);
  179.         
  180.         /* Read next line and check if it is a continuation line. */
  181.         while ((more = fgets(buf, sizeof(buf), fd) != 0) != 0) {
  182.             ch = buf[0];
  183.             if (ch == '\n' || (ch != ' ' && ch != '\t'))
  184.             break;
  185.             putAddresses(socket, buf);
  186.         }
  187.         
  188.         continue;
  189.         }
  190.     
  191.         more = fgets(buf, sizeof(buf), fd) != 0;
  192.     }
  193.     }
  194.  
  195.     /* Send the DATA command and the mail message line by line. */
  196.     socket.puts("DATA");
  197.     if ( !getSmtpReply(socket, "354")) {
  198.     return 0;
  199.     }
  200.  
  201.     fseekT(fd, offset, SEEK_SET);
  202.     count = bytes;
  203.     while (fgetsT(buf, sizeof(buf), fd) && count > 0) {
  204.     count -= strlen(buf);
  205.     if ((s = strchr(buf, '\n')) != NULL)
  206.         *s = '\0';
  207.     if (buf[0] == '.') {
  208.         socket.printf(".");               //  write an extra .
  209.     }
  210.     socket.printf("%s\n", buf);
  211.     }
  212.     fseekT(fd, offset+bytes, SEEK_SET);
  213.  
  214.     socket.puts(".");
  215.     getSmtpReply(socket, "250");
  216.  
  217.     return 1;
  218. }   // smtpMail
  219.